#include "scl.h"
#include <iostream>
#include <cstring>
#include <algorithm>

// ====================== CN_SUNIST_PREVDEFINE_START ====================== //
// ======================= CN_SUNIST_PREVDEFINE_END ======================= //










// ======================= CN_SUNIST_ALGORITHM_START ====================== //
template<typename ElemType> bool cn_sunist_datastructure_algorithm::memcompare(ElemType a, ElemType b) {
    return memcmp(&a, &b, sizeof(ElemType)) == 0;
}

template<typename ElemType> void cn_sunist_datastructure_algorithm::quick_sort(int start, int end, ElemType* arr, bool compare(ElemType, ElemType)) {
    if (start >= end || start < 0) {
        return;
    }
    ElemType base, temp;
    int i = start; int j = end;
    base = arr[start];
    while (i < j) {
        while (compare(base, arr[j]) && i < j) {
            j--;
        }
        while (!compare(base, arr[i]) && i < j) {
            i++;
        }
        if (i < j) {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    arr[start] = arr[i];
    arr[i] = base;
    quick_sort(start, i - 1, arr, compare);
    quick_sort(i + 1, end, arr, compare);
}

int cn_sunist_datastructure_algorithm::LCS_Length(std::string a, std::string b) {
    const char* cstra = a.c_str();
    const char* cstrb = b.c_str();
    int maxlen = a.length()>b.length() ? a.length() : b.length(); maxlen += 2;
    int **dp = new int*[maxlen];
    for (int i = 0; i < maxlen; i++) {
        dp[i] = new int[maxlen];
        for (int j = 0; j < maxlen; j++) {
            dp[i][j] = 0;
        }
    }
    for (int i = 1; i <= a.length(); i++) {
        for (int j = 1; j <= b.length(); j++) {
            if (cstra[i-1] == cstrb[j-1]) {
                dp[i][j] = dp[i-1][j-1] + 1;
            }
            else {
                dp[i][j] = dp[i-1][j]>dp[i][j-1] ? dp[i-1][j] : dp[i][j-1];
            }
        }
    }
    return dp[a.length()][b.length()];
}

std::string cn_sunist_datastructure_algorithm::LCS_String(std::string a, std::string b) {
    std::string rtn = "";
    const char* cstra = a.c_str();
    const char* cstrb = b.c_str();
    int maxlen = a.length()>b.length() ? a.length() : b.length(); maxlen += 2;
    int **dp = new int*[maxlen];
    for (int i = 0; i < maxlen; i++) {
        dp[i] = new int[maxlen];
        for (int j = 0; j < maxlen; j++) {
            dp[i][j] = 0;
        }
    }
    for (int i = 1; i <= a.length(); i++) {
        for (int j = 1; j <= b.length(); j++) {
            if (cstra[i-1] == cstrb[j-1]) {
                dp[i][j] = dp[i-1][j-1] + 1;
            }
            else {
                dp[i][j] = dp[i-1][j]>dp[i][j-1] ? dp[i-1][j] : dp[i][j-1];
            }
        }
    }
    int i = a.length(), j = b.length();
    cn_sunist_datastructure_library::LinkedStack<char> stk;
    while (dp[i][j]) {
        if(dp[i][j]==dp[i-1][j]) {
            i--;
        }
        else if(dp[i][j]==dp[i][j-1]) {
            j--;
        }
        else if(dp[i][j]>dp[i-1][j-1]) {
            i--; j--;
            stk.Push(cstra[i]);
        }
    }
    while (!stk.Empty()) {
        rtn += stk.Top();
        stk.Pop();
    }
    return rtn;
}
// ======================== CN_SUNIST_ALGORITHM_END ======================= //










// ================= CN_SUNIST_DATASTRUCTURE_PREVLIB_START ================ //
// <!--LinkedListNode--!> //
template<typename ElemType> cn_sunist_datastructure_prevlib::LinkedListNode<ElemType>::LinkedListNode () {
    nextNode = nullptr;
    prevNode = nullptr;
    innerData = *(new ElemType);
}

template<typename ElemType> cn_sunist_datastructure_prevlib::LinkedListNode<ElemType>::LinkedListNode (ElemType data) {
    nextNode = nullptr;
    prevNode = nullptr;
    innerData = data;
}

template<typename ElemType> ElemType& cn_sunist_datastructure_prevlib::LinkedListNode<ElemType>::Data() {
    return innerData;
}

// <!--LinkedArrayList--!> //
template<typename ElemType> cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::LinkedArrayListNode(int size) {
    innerData = new ElemType[size];
    defineSize = size;
    startIndex = 0;
    usedSize = 0;
    nextNode = nullptr;
    prevNode = nullptr;
}

template<typename ElemType> cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::LinkedArrayListNode(const LinkedArrayListNode<ElemType>& list) {
    memcpy(this, &list, sizeof(list));
}

template<typename ElemType> int cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::DefineSize() {
    return defineSize;
}

template<typename ElemType> int cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::UsedSize() {
    return usedSize;
}

template<typename ElemType> int cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Locate(ElemType data, bool compare(ElemType)) {
    for (int i = 0; i < defineSize; i++) {
        if (compare(innerData[i])) {
            return i;
        }
    }
    return -1;
}

template<typename ElemType> bool cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Empty() {
    return usedSize == 0;
}

template<typename ElemType> bool cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Filled() {
    return usedSize == defineSize;
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Initialize(ElemType data) {
    for (int i = 0; i < defineSize; i++) {
        innerData[i] = data;
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Initialize(ElemType ctor(int)) {
    for (int i = 0; i < defineSize; i++) {
        innerData = ctor(i);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Push_Front(ElemType data) {
    if (!Filled()) {
        for (int i = usedSize; i > 0; i--) {
            at(i) = at(i - 1);
        }
        at(0) = data;
        usedSize += 1;
        return success;
    }
    else {
        if (nextNode != nullptr) {
            nextNode->Push_Front(at(defineSize - 1));
            at(defineSize - 1) = data;
            startIndex -= 1;
            return success;
        }
        else {
            nextNode = new LinkedArrayListNode<ElemType>(defineSize);
            nextNode->prevNode = this;
            nextNode->Push_Front(at(defineSize - 1));
            at(defineSize - 1) = data;
            startIndex -= 1;
            return success;
        }
    }
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Push_Back(ElemType data) {
    if (!Filled()) {
        at(usedSize) = data;
        usedSize += 1;
        return success;
    }
    else {
        if (nextNode != nullptr) {
            nextNode->Push_Front(data);
        }
        else {
            LinkedArrayListNode<ElemType>* newNode = new LinkedArrayListNode<ElemType>(defineSize);
            nextNode = newNode;
            nextNode->prevNode = this;
            try {
                nextNode->Push_Front(data);
            }
            catch (std::exception& e) {
                std::cerr << e.what() << std::endl;
            }
        }
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Pop_Front() {
    if (!Filled()) {
        memset(&at(0), 0, sizeof(ElemType));
        startIndex += 1;
        usedSize -= 1;
        return success;
    }
    else {
        if (nextNode != nullptr) {
            startIndex += 1;
            usedSize -= 1;
            Push_Back(nextNode->at(0));
            return nextNode->Pop_Front();
        }
        else {
            startIndex += 1;
            usedSize -= 1;
            return success;
        }
    }
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Pop_Back() {
    return Erase(usedSize - 1);
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Insert(int index, ElemType data) {
    if (index < 0 || index >= defineSize) {
        return overflow;
    }
    if (!Filled()) {
        for (int i = defineSize - 1; i >= index; i--) {
            at(i) = at(i - 1);
        }
        at(index) = data;
        return success;
    }
    else {
        if (nextNode != nullptr) {
            nextNode->Push_Front(at(defineSize - 1));
            for (int i = defineSize - 1; i >= index; i--) {
                at(i) = at(i - 1);
            }
            at(index) = data;
            return success;
        }
        else {
            nextNode = new LinkedArrayListNode<ElemType>(defineSize);
            nextNode->Push_Front(at(defineSize - 1));
            for (int i = defineSize - 1; i >= index; i--) {
                at(i) = at(i - 1);
            }
            at(index) = data;
            return success;
        }
    }
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Erase(int index) {
    if (index < 0 || index >= defineSize) {
        return overflow;
    }
    if (nextNode == nullptr) {
        for (int i = index; i < defineSize - 1; i++) {
            at(i) = at(i + 1);
        }
        usedSize -= 1;
        return success;
    }
    else {
        for (int i = index; i < defineSize - 1; i++) {
            at(i) = at(i + 1);
        }
        usedSize -= 1;
        Push_Back(nextNode->at(0));
        return nextNode->Pop_Front();
    }
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Sort(int start, int end, bool compare(ElemType, ElemType), SortMode mode) {
    if (start < 0 || end >= defineSize || start >= defineSize || end < 0 || end < start) {
        return overflow;
    }
    if (mode == stlsort) {
        ElemType* temp = new ElemType[end - start + 1];
        for (int i = 0; i < end - start + 1; i++) {
            temp[i] = at(start + i);
        }
        std::sort(temp, temp + end - start + 1, compare);
        for (int i = 0; i < end - start + 1; i++) {
            at(start + i) = temp[i];
        }
        return success;
    }
    return argumenterror;
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Unique(int start, int end, bool compare(ElemType, ElemType)) {
    if (start < 0 || end >= defineSize || start >= defineSize || end < 0 || end < start) {
        return overflow;
    }
    for (int i = start; i <= end; i++) {
        for (int j = i + 1; j < defineSize; j++) {
            if (compare(at(i), at(j))) {
                Erase(j);
            }
        }
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Swap(int index_a, int index_b) {
    if (index_a < 0 || index_a >= defineSize || index_b >= defineSize || index_b < 0) {
        return overflow;
    }
    ElemType temp = at(index_a);
    at(index_a) = at(index_b);
    at(index_b) = temp;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::Reverse(int start, int end) {
    if (start < 0 || end >= defineSize || start >= defineSize || end < 0 || end < start) {
        return overflow;
    }
    for (int i = 0; i < (end - start) / 2 + 1; i++) {
        Swap(start + i, end - i);
    }
    return success;
}

template<typename ElemType> ElemType& cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::at(int index, bool isOriginal) {
    if (index < 0) {
        ElemType* x = new ElemType;
        return *x;
    }
    if (!isOriginal) {
        int realIndex = startIndex + index;
        while (realIndex > defineSize) {
            realIndex -= defineSize;
        }
        while (realIndex < 0) {
            realIndex += defineSize;
        }
        return innerData[realIndex];
    }
    else {
        if (index >= defineSize && nextNode == nullptr) {
            ElemType* x = new ElemType;
            return *x;
        }
        if (index >= defineSize && nextNode != nullptr) {
            return nextNode->at(index - defineSize);
        }
        else {
            return at(index);
        }
    }
}

template<typename ElemType> ElemType& cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::operator[] (int index) {
    return at(index);
}

template<typename ElemType> void cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::operator+= (ElemType data) {
    Push_Back(data);
}

template<typename ElemType> void cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>::operator-= (ElemType data) {
    for (int i = 0; i < usedSize; i++) {
        if (cn_sunist_datastructure_algorithm::memcompare(innerData[i], data) == 0) {
            Erase(i);
        }
    }
}
// ================== CN_SUNIST_DATASTRUCTURE_PREVLIB_END ================= //










// ================= CN_SUNIST_DATASTRUCTURE_LIBRARY_START ================ //
// <!--LinkedList--!> //
template<typename ElemType> cn_sunist_datastructure_prevlib::LinkedListNode<ElemType>* cn_sunist_datastructure_library::LinkedList<ElemType>::at(
        int index) {
    if (index < 0) {
        return head;
    }
    if (index >= length-1) {
        return rear;
    }
    cn_sunist_datastructure_prevlib::LinkedListNode<ElemType>* rtn = head->nextNode;
    for (int i = 0; i < index; i++) {
        rtn = rtn->nextNode;
    }
    return rtn;
}

template<typename ElemType> cn_sunist_datastructure_library::LinkedList<ElemType>::LinkedList () {
    head = new cn_sunist_datastructure_prevlib::LinkedListNode<ElemType>;
    rear = head;
    length = 0;
}

template<typename ElemType> int cn_sunist_datastructure_library::LinkedList<ElemType>::Length() {
    return length;
}

template<typename ElemType> bool cn_sunist_datastructure_library::LinkedList<ElemType>::Empty() {
    return length == 0;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Push_Front(ElemType data) {
    cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> *newNode = new cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> (data);
    if (length == 0) {
        head->nextNode = newNode;
        newNode->prevNode = head;
        rear = newNode;
        length += 1;
    }
    else {
        newNode->prevNode = head;
        newNode->nextNode = head->nextNode;
        head->nextNode->prevNode = newNode;
        head->nextNode = newNode;
        length += 1;
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Push_Back(ElemType data) {
    if (length == 0) {
        return Push_Front(data);
    }
    else {
        cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> *newNode = new cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> (data);
        rear->nextNode=newNode;
        newNode->prevNode=rear;
        rear = newNode;
        length += 1;
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Pop_Front() {
    if (length == 0) {
        return overflow;
    }
    else {
        cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> *temp = head->nextNode;
        head->nextNode = temp->nextNode;
        temp->prevNode = head;
        delete temp;
        length -= 1;
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Pop_Back() {
    if (length == 0) {
        return overflow;
    }
    else {
        rear = rear->prevNode;
        delete rear->nextNode;
        rear->nextNode = nullptr;
        length -= 1;
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Insert(int index, ElemType data) {
    if (index < 0) {
        return Push_Front(data);
    }
    else if (index >= length) {
        return Push_Back(data);
    }
    else {
        cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> *temp = at(index);
        cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> *newNode = new cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> (data);
        newNode->nextNode = temp;
        newNode->prevNode = temp->prevNode;
        temp->prevNode->nextNode = newNode;
        temp->prevNode = newNode;
        length += 1;
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Erase(int index) {
    if (index < 0) {
        return Pop_Front();
    }
    else if (index >= length) {
        return Pop_Back();
    }
    else {
        cn_sunist_datastructure_prevlib::LinkedListNode<ElemType> *temp = at(index);
        temp->prevNode->nextNode = temp->nextNode;
        temp->nextNode->prevNode = temp->prevNode;
        delete temp;
        length -= 1;
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Sort(int start, int end, bool (*compare)(ElemType, ElemType)) {
    if (start < 0 || start >= length || end < 0 || end >= length || end < start) {
        return overflow;
    }
    else {
        ElemType* temp = new ElemType[length];
        for(int i = 0; i < length; i++) {
            temp[i] = at(i)->Data();
        }
        std::sort(temp, temp+length, compare);
        for (int i = 0; i < length; i++) {
            at(i)->Data() = temp[i];
        }
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Swap(int index_a, int index_b) {
    if (index_a < 0 || index_a >= length || index_b < 0 || index_b >= length) {
        return overflow;
    }
    else {
        ElemType temp = at(index_a)->Data();
        at(index_a)->Data() = at(index_b)->Data();
        at(index_b)->Data() = temp;
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Unique(int start, int end, bool (*compare)(ElemType, ElemType)) {
    if (start < 0 || start >= length || end < 0 || end >= length || end < start) {
        return overflow;
    }
    for (int i = start; i <= end; i++) {
        for (int j = i+1; j <= end; j++) {
            if (compare(at(i)->Data, at(j)->Data())) {
                Erase(j);
                end = end<length ? end : length;
                j--; continue;
            }
        }
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedList<ElemType>::Reverse(int start, int end) {
    if (start < 0 || start >= length || end < 0 || end >= length || end < start) {
        return overflow;
    }
    for (int i = 0; i < (end-start)/2+1; i++) {
        Swap(start+i, end-i);
    }
    return success;
}

template<typename ElemType> ElemType& cn_sunist_datastructure_library::LinkedList<ElemType>::operator[](int index) {
    return at(index)->Data();
}

// <!--LinkedArrayList--!> //
template<typename ElemType> cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>* cn_sunist_datastructure_library::LinkedArrayList<ElemType>::at(int index) {
    if (index < 0 || index > usedSize) {
        return nullptr;
    }
    int temp = usedSize;
    index /= defaultNodeSize; temp /= defaultNodeSize;
    cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>* rtnptr = head;
    for (int i = 0; i < index; i++) {
        rtnptr = rtnptr->nextNode;
    }
    return rtnptr;
}

template<typename ElemType> ElemType& cn_sunist_datastructure_library::LinkedArrayList<ElemType>::atelem(int index) {
    if (index < 0) {
        return head->at(0);
    }
    else if (index >= usedSize) {
        return rear->at(rear->UsedSize());
    }
    else {
        cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>* temp = at(index);
        return temp->at(index % defaultNodeSize);
    }
}

template<typename ElemType> void cn_sunist_datastructure_library::LinkedArrayList<ElemType>::quick_Sort(int start, int end, bool compare(ElemType, ElemType)) {
    if (start > end || start < 0) {
        return;
    }
    ElemType base, temp;
    int i = start, j = end;
    base = atelem(start);
    while (i < j) {
        while (compare(base, atelem(j)) && i < j) {
            j--;
        }
        while (compare(base, atelem(i)) && i < j) {
            i++;
        }
        if (i < j) {
            temp = atelem(i);
            atelem(i) = atelem(j);
            atelem(j) = temp;
        }
    }
    atelem(start) = atelem(i);
    atelem(i) = base;
    quick_Sort(start, i - 1, compare);
    quick_Sort(i + 1, end, compare);
}

template<typename ElemType> cn_sunist_datastructure_library::LinkedArrayList<ElemType>::LinkedArrayList(int defaultsize) {
    defaultNodeSize = defaultsize;
    usedSize = 0;
    head = new cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>(defaultNodeSize);
    mid = head;
    rear = head;
    nullemt = *(new ElemType);
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Initialize(ElemType data) {
    for (int i = 0; i < usedSize; i++) {
        atelem(i) = data;
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Initialize(ElemType ctor(int)) {
    for (int i = 0; i < usedSize; i++) {
        atelem(i) = ctor(i);
    }
    return success;
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Head() {
    if (!Empty()) {
        return head->at(0);
    }
    else {
        return nullemt;
    }
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Rear() {
    if (!Empty()) {
        return rear->at(rear->UsedSize()-1);
    }
    else {
        return nullemt;
    }
}

template<typename ElemType> int cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Length() {
    return usedSize;
}

template<typename ElemType> int cn_sunist_datastructure_library::LinkedArrayList<ElemType>::DefaultSize() {
    return defaultNodeSize;
}

template<typename ElemType> bool cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Empty() {
    return usedSize == 0;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Front(ElemType data) {
    Status rtn = head->Push_Front(data);
    usedSize += 1;
    while (rear->nextNode != nullptr) {
        rear = rear->nextNode;
    }
    return rtn;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Front(ElemType* dataArr, int len) {
    for (int i = 0; i < len; i++) {
        Push_Front(dataArr[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Front(ElemType* dataArr, int start, int end) {
    if (start < 0 || start >= usedSize || end < 0 || end >= usedSize) {
        return overflow;
    }
    else {
        for (int i = start; i <= end; i++) {
            Push_Front(dataArr[i]);
        }
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Front(cn_sunist_datastructure_library::LinkedArrayList<ElemType> list) {
    for (int i = 0; i < list.Length(); i++) {
        Push_Front(list[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Front(cn_sunist_datastructure_library::LinkedArrayList<ElemType> list, int start, int end) {
    if (start < 0 || start >= list.Length() || end < 0 || end >= list.Length() || start > end) {
        return overflow;
    }
    for (int i = start; i <= end; i++) {
        Push_Front(list[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Back(ElemType data) {
    Status rtn = rear->Push_Back(data);
    usedSize += 1;
    while (rear->nextNode != nullptr) {
        rear = rear->nextNode;
    }
    return rtn;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Back(ElemType* dataArr, int len) {
    for (int i = 0; i < len; i++) {
        Push_Back(dataArr[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Back(ElemType* dataArr, int start, int end) {
    if (start < 0 || start >= usedSize || end < 0 || end >= usedSize) {
        return overflow;
    }
    else {
        for (int i = start; i <= end; i++) {
            Push_Back(dataArr[i]);
        }
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Back(cn_sunist_datastructure_library::LinkedArrayList<ElemType> list) {
    for (int i = 0; i < list.Length(); i++) {
        Push_Back(list[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Push_Back(cn_sunist_datastructure_library::LinkedArrayList<ElemType> list, int start, int end) {
    if (start < 0 || start >= list.Length() || end < 0 || end >= list.Length() || start > end) {
        return overflow;
    }
    else {
        for (int i = start; i <= end; i++) {
            Push_Back(list[i]);
        }
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Insert(int index, ElemType data) {
    if (index < 0) {
        return Push_Front(data);
    }
    else if (index >= usedSize) {
        return Push_Front(data);
    }
    else {
        cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>* temp = at(index);
        index %= defaultNodeSize;
        Status rtn = temp->Insert(index, data);
        usedSize += 1;
        while (rear->nextNode != nullptr) {
            rear = rear->nextNode;
        }
        return rtn;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Insert(int index, ElemType* dataArr, int len) {
    for (int i = 0; i < len; i++) {
        Insert(index + i, dataArr[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Insert(int index, ElemType* dataArr, int start, int end) {
    for (int i = 0; i < end - start + 1; i++) {
        Insert(index + i, dataArr[start + i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Insert(int index, LinkedArrayList<ElemType> list) {
    for (int i = 0; i < list.Length(); i++) {
        Insert(index + i, list[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Insert(int index, LinkedArrayList<ElemType> list, int start, int end) {
    if (start < 0 || end < 0 || start >= list.Length() || end >= list.Length() || start > end) {
        return overflow;
    }
    for (int i = 0; i < end - start + 1; i++) {
        Insert(index + i, list[i]);
    }
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Erase(int index) {
    if (index < 0) {
        return Pop_Front(1);
    }
    else if (index >= usedSize) {
        return Pop_Back(1);
    }
    else {
        cn_sunist_datastructure_prevlib::LinkedArrayListNode<ElemType>* temp = at(index);
        index %= defaultNodeSize;
        Status rtn = temp->Erase(index);
        usedSize -= 1;
        if (rear->UsedSize() == 0) {
            rear = rear->prevNode;
            delete rear->nextNode;
            rear->nextNode = nullptr;
        }
        return rtn;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Erase(int start, int end) {
    if (start < 0 || start >= usedSize || end < 0 || end >= usedSize) {
        return overflow;
    }
    else {
        for (int i = start; i <= end; i++) {
            Erase(i);
        }
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Pop_Front(int len) {
    if (len == 1) {
        Status rtn = head->Pop_Front();
        usedSize -= 1;
        if (rear->Empty() && rear != head) {
            rear = rear->prevNode;
            delete rear->nextNode;
            rear->nextNode = nullptr;
        }
        return rtn;
    }
    else {
        for (int i = 0; i < len; i++) {
            Pop_Front(1);
        }
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Pop_Back(int len) {
    if (len == 1) {
        Status rtn = rear->Pop_Back();
        usedSize -= 1;
        if (rear->Empty() && rear != head) {
            rear = rear->prevNode;
            delete rear->nextNode;
            rear->nextNode = nullptr;
        }
        return rtn;
    }
    else {
        for (int i = 0; i < len; i++) {
            Pop_Back(1);
        }
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Sort(int start, int end, bool compare(ElemType, ElemType), SortMode mode) {
    if (mode == stlsort) {
        ElemType* temp = new ElemType[usedSize];
        for (int i = 0; i < usedSize; i++) {
            temp[i] = atelem(i);
        }
        std::sort(temp, temp + usedSize, compare);
        for (int i = 0; i < usedSize; i++) {
            atelem(i) = temp[i];
        }
        return success;
    }
    else if (mode == quicksort) {
        quick_Sort(start, end, compare);
        return success;
    }
    else if (mode == bubblesort) {
        bool isSorted = false;
        while (!isSorted) {
            isSorted = true;
            for (int i = start; i < end; i++) {
                if (!compare(atelem(i), atelem(i + 1))) {
                    Swap(i, i + 1);
                    isSorted = false;
                }
            }
            end--;
        }
        return success;
    }
    else { // todo fill the other mode
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Unique(int start, int end, bool compare(ElemType, ElemType), bool sorted) {
    if (start < 0 || end < 0 || start >= usedSize || end >= usedSize || end <start) {
        return overflow;
    }
    if (!sorted) {
        for (int i = start; i <= end; i++) {
            for (int j = i + 1; j <= end; j++) {
                if (compare(atelem(i), atelem(j))) {
                    Erase(j);
                    end = end < usedSize ? end : usedSize;
                    j--; continue;
                }
            }
        }
        return success;
    }
        // todo fix the bug when sorted!
    else {
        for (int i = start; i <= end; i++) {
            if (compare(atelem(i), atelem(i+1))) {
                Erase(i);
                end = end < usedSize ? end : usedSize;
            }
        }
        return success;
    }
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Swap(int index_a, int index_b) {
    ElemType temp = atelem(index_a);
    atelem(index_a) = atelem(index_b);
    atelem(index_b) = temp;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedArrayList<ElemType>::Reverse(int start, int end) {
    if (start < 0 || end < 0 || start >= usedSize || end >= usedSize || end < start) {
        return overflow;
    }
    for (int i = 0; i < (end - start) / 2 + 1; i++) {
        Swap(start + i, end - i);
    }
    return success;
}

template<typename ElemType> ElemType& cn_sunist_datastructure_library::LinkedArrayList<ElemType>::operator[](int index) {
    return atelem(index);
}

// <!--ArrayList--!> //
template<typename ElemType> cn_sunist_datastructure_library::ArrayList<ElemType>::ArrayList (int size) {
    NullNode = *(ElemType*)memset(&NullNode, 0, sizeof(NullNode));
    Data = new ElemType[size];
    definesize = size;
}

template<typename ElemType> cn_sunist_datastructure_library::ArrayList<ElemType>::ArrayList (const ArrayList<ElemType>& another) {
    NullNode = *(ElemType*)memset(&NullNode, 0, sizeof(NullNode));
    definesize = another.size();
    Data = new ElemType[another.size()];
    for (int i = 0; i < definesize; i++) {
        Data[i] = another.Data[i];
    }
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Resize(int size) {
    try {
        int movestep = size > definesize ? definesize : size;
        ElemType* newData = new ElemType[size];
        for (int i = 0; i < movestep; i++) {
            newData[i] = Data[i];
        }
        delete[] Data;
        Data = newData;
        definesize = size;
        return true;
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << '\n';
        return false;
    }
}

template<typename ElemType> int cn_sunist_datastructure_library::ArrayList<ElemType>::Size() {
    return definesize;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Empty() {
    return definesize == 0;
}

template<typename ElemType> ElemType* cn_sunist_datastructure_library::ArrayList<ElemType>::Head() {
    return Data;
}

template<typename ElemType> ElemType* cn_sunist_datastructure_library::ArrayList<ElemType>::End() {
    return Data + definesize;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Push_Front(ElemType data) {
    if (!Resize(definesize + 1)) {
        return false;
    }
    for (int i = definesize; i > 0; i--) {
        Data[i] = Data[i - 1];
    }
    Data[0] = data;
    return true;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Push_Back(ElemType data) {
    if (!Resize(definesize + 1)) {
        return false;
    }
    Data[definesize - 1] = data;
    return true;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Pop_Front() {
    if (definesize <= 0) {
        return false;
    }
    return Erase(0);
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Pop_Back() {
    if (definesize <= 0) {
        return false;
    }
    return Erase(definesize - 1);
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Insert(int index, ElemType data) {
    if (index >= definesize) {
        return Push_Back(data);
    }
    if (!Resize(definesize + 1)) {
        return false;
    }
    for (int i = definesize - 1; i >= index; i--) {
        Data[i] = Data[i - 1];
    }
    Data[index] = data;
    return true;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Insert(int start_index, ElemType* data, int len) {
    for (int i = 0; i < len; i++) {
        if (!Insert(start_index + i, data[i])) {
            return false;
        }
    }
    return true;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Insert(int start_index, ArrayList<ElemType> another) {
    for (int i = 0; i < another.Size(); i++) {
        if (!Insert(start_index + i, another[i])) {
            return false;
        }
    }
    return true;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Erase(int index) {
    if (definesize <= 0 || index > definesize) {
        return false;
    }
    for (int i = index; i < Size(); i++) {
        Data[i] = Data[i + 1];
    }
    return Resize(definesize - 1);
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Erase(int start_index, int end_index) {
    if (end_index < start_index) {
        return false;
    }
    for (int i = start_index; i <= end_index; i++) {
        if (!Erase(start_index)) {
            return false;
        }
    }
    return true;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Clear(int start_index, int end_index) {
    if (definesize <= 0 || start_index > definesize || end_index < start_index) {
        return false;
    }
    for (int i = start_index; i <= end_index; i++) {
        Data[i] = NullNode;
    }
    return true;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Sort(bool compare(ElemType, ElemType), ElemType start_index, ElemType end_index, SortMode mode) {
    if (mode == stlsort) {
        std::sort(&Data[start_index], &Data[end_index], compare);
        return true;
    }
    else if (mode == bubblesort) {
        bool isSorted = false;
        while (!isSorted) {
            isSorted = true;
            for (int i = start_index; i < end_index; i++) {
                if (!compare(Data[i], Data[i + 1])) {
                    Swap(i, i + 1);
                    isSorted = false;
                }
            }
            end_index--;
        }
        return true;
    }
    else if (mode == shellsort) {
        int step;
        step = (end_index - start_index) / 2;
        if (step % 2 == 0) {
            step++;
        }
        while (step > 0) {
            for (int j = step; j < end_index - start_index; j++) {
                int temp = Data[start_index + j];
                int i = j - step;
                while (i >= 0 && !compare(Data[start_index + i], temp)) {
                    Data[start_index + i + step] = Data[start_index + i];
                    i = i - step;
                }
                if (i != j - step) {
                    Data[start_index + i + step] = temp;
                }
            }
            if (step == 1) {
                break;
            }
            step = step / 2;
            if (step % 2 == 0) {
                step++;
            }
        }
        return true;
    }
    else if (mode == selectsort) {
        int minindex, temp;
        for (int i = 0; i < (end_index - start_index) - 1; i++) {
            minindex = i;
            for (int j = i + 1; j < (end_index - start_index); j++) {
                if (compare(Data[start_index + j], Data[start_index + minindex])) {
                    minindex = j;
                }
            }
            temp = Data[start_index + i];
            Data[start_index + i] = Data[start_index + minindex];
            Data[start_index + minindex] = temp;
        }
        return true;
    }
    else if (mode == insertsort) {
        for (int i = 1; i < (end_index - start_index); i++) {
            for (int j = i - 1; j >= 0 && compare(Data[start_index + j + 1], Data[start_index + j]); j--) {
                Swap(start_index + j, start_index + j + 1);
            }
        }
        return true;
    }
    else if (mode == quicksort) {
        quick_sort(start_index, end_index, Data, definesize, compare);
        return true;
    }
    return false;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Reverse(int start_index, int end_index) {
    if (start_index < 0 || end_index >= definesize || end_index < start_index) {
        return false;
    }
    for (int i = 0; i < (end_index - start_index) / 2 + 1; i++) {
        if (!Swap(start_index + i, end_index - i)) {
            return false;
        }
    }
    return true;
}

template<typename ElemType> int cn_sunist_datastructure_library::ArrayList<ElemType>::Unique(int start_index, int end_index, bool compare(ElemType, ElemType)) {
    if (start_index < 0 || end_index >= definesize || end_index < start_index) {
        return -2;
    }
    int count = 0;
    for (int i = 0; i < definesize; i++) {
        for (int j = i + 1; j < definesize; j++) {
            if (compare(Data[i], Data[j])) {
                count += 1;
                if (!Erase(j)) {
                    return -1;
                }
            }
        }
    }
    return count;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Swap(int index_a, int index_b) {
    if (index_a >= definesize || index_b >= definesize || index_a < 0 || index_b < 0) {
        return false;
    }
    ElemType temp = Data[index_a];
    Data[index_a] = Data[index_b];
    Data[index_b] = temp;
    return true;
}

template<typename ElemType> int cn_sunist_datastructure_library::ArrayList<ElemType>::Locate(bool compare(ElemType)) {
    for (int i = 0; i < definesize; i++) {
        if (compare(Data[i])) {
            return i;
        }
    }
    return -1;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Merge(ArrayList<ElemType> another) {
    return Insert(definesize, another);
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayList<ElemType>::Union(ArrayList<ElemType> another, bool cmp(ElemType, ElemType)) {
    bool* tag = new bool[definesize];
    for (int i = 0; i < definesize; i++) {
        tag[i] = false;
    }
    for (int i = 0; i < definesize; i++) {
        for (int j = 0; j < another.size(); j++) {
            if (cmp(Data[i], another.Data[j])) {
                tag[i] = true;
            }
        }
    }
    int temp = 0;
    for (int i = 0; i < definesize; i++) {
        if (!tag[i]) {
            Erase(i - temp);
            temp++;
        }
    }
    delete[] tag;
    return true;
}

template<typename ElemType> cn_sunist_datastructure_library::ArrayList<ElemType> cn_sunist_datastructure_library::ArrayList<ElemType>::operator + (cn_sunist_datastructure_library::ArrayList<ElemType> another) {
    ArrayList<ElemType> newList = *(new ArrayList<ElemType>(0));
    for (int i = 0; i < definesize; i++) {
        newList.Push_Back(Data[i]);
    }
    newList.Merge(another);
    return newList;
}

template<typename ElemType> cn_sunist_datastructure_library::ArrayList<ElemType> cn_sunist_datastructure_library::ArrayList<ElemType>::operator - (ArrayList<ElemType> another) {
    ArrayList<ElemType> newList = *(new ArrayList<ElemType>(0));
    for (int i = 0; i < definesize; i++) {
        newList.Push_Back(Data[i]);
    }
    for (int i = 0; i < another.size(); i++) {
        for (int j = 0; j < newList.size(); j++) {
            if (cn_sunist_datastructure_algorithm::memcompare(another.Data[i], newList.Data[j])) {
                newList.Erase(j);
            }
        }
    }
    return newList;
}

template<typename ElemType> ElemType& cn_sunist_datastructure_library::ArrayList<ElemType>::operator [] (int index) {
    return Data[index];
}

template<typename ElemType> void cn_sunist_datastructure_library::ArrayList<ElemType>::operator += (ArrayList<ElemType> another) {
    Merge(another);
}

template<typename ElemType> void cn_sunist_datastructure_library::ArrayList<ElemType>::operator -= (ArrayList<ElemType> another) {
    for (int i = 0; i < another.size(); i++) {
        for (int j = 0; j < definesize; j++) {
            if (cn_sunist_datastructure_algorithm::memcompare(another.Data[i], Data[j])) {
                Erase(j);
            }
        }
    }
}

// <!--LinearSet---!> //
template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>::LinearSet (int defaultNodeSize) {
    DefaultSize = defaultNodeSize;
    list = *(new cn_sunist_datastructure_library::LinkedArrayList<ElemType> (DefaultSize));
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinearSet<ElemType>::Set(LinkedArrayList <ElemType> list) {
    if (list.DefaultSize() != this->list.DefaultSize()) {
        return argumenterror;
    }
    else {
        this->list = list;
        return success;
    }
}

template<typename ElemType>  cn_sunist_datastructure_library::LinkedArrayList<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::Get() {
    return list;
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::Add (LinearSet <ElemType> set, bool cmp(ElemType, ElemType)) {
    LinkedArrayList<ElemType> anslist = list;
    anslist.Push_Back(set.Get());
    anslist.Unique(0,anslist.Length()-1,cmp);
    cn_sunist_datastructure_library::LinearSet<ElemType>* ans = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    ans->Set(anslist);
    return *ans;
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::Div (LinearSet <ElemType> set, bool cmp(ElemType, ElemType)) {
    LinkedArrayList<ElemType> anslist = list;
    for (int i = 0; i < set.Get().Length(); i++) {
        for (int j = 0; j < anslist.Length(); j++) {
            if (cmp(set.Get()[i], anslist[j])) {
                anslist.Erase(j);
                j--; continue;
            }
        }
    }
    cn_sunist_datastructure_library::LinearSet<ElemType>* ans = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    ans->Set(anslist);
    return *ans;
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::Meg (LinearSet <ElemType> set, bool cmp(ElemType, ElemType)) {
    LinkedArrayList<ElemType> anslist(DefaultSize);
    for (int i = 0; i < list.Length(); i++) {
        for (int j = 0; j < set.Get().Length(); j++) {
            if (cmp(list[i], set.Get()[j])) {
                anslist.Push_Back(list[i]);
            }
        }
    }
    anslist.Unique(0, anslist.Length()-1,cmp);
    cn_sunist_datastructure_library::LinearSet<ElemType>* ans = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    ans->Set(anslist);
    return *ans;
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::Usf (LinearSet <ElemType> set, bool cmp(ElemType, ElemType)) {
    cn_sunist_datastructure_library::LinearSet<ElemType> *temp = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    temp->Set(list);
    return Div(*temp, cmp);
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::operator + (LinearSet <ElemType> set) {
    LinkedArrayList<ElemType> anslist = list;
    anslist.Push_Back(set.Get());
    anslist.Unique(0,anslist.Length()-1);
    cn_sunist_datastructure_library::LinearSet<ElemType>* ans = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    ans->Set(anslist);
    return *ans;
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::operator - (LinearSet <ElemType> set) {
    LinkedArrayList<ElemType> anslist = list;
    for (int i = 0; i < set.Get().Length(); i++) {
        for (int j = 0; j < anslist.Length(); j++) {
            if (cn_sunist_datastructure_algorithm::memcompare(set.Get()[i], anslist[j])) {
                anslist.Erase(j);
                j--; continue;
            }
        }
    }
    cn_sunist_datastructure_library::LinearSet<ElemType>* ans = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    ans->Set(anslist);
    return *ans;
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::operator ^ (LinearSet <ElemType> set) {
    LinkedArrayList<ElemType> anslist(DefaultSize);
    for (int i = 0; i < list.Length(); i++) {
        for (int j = 0; j < set.Get().Length(); j++) {
            if (cn_sunist_datastructure_algorithm::memcompare(list[i], set.Get()[j])) {
                anslist.Push_Back(list[i]);
            }
        }
    }
    anslist.Unique(0, anslist.Length()-1);
    cn_sunist_datastructure_library::LinearSet<ElemType>* ans = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    ans->Set(anslist);
    return *ans;
}

template<typename ElemType> cn_sunist_datastructure_library::LinearSet<ElemType>& cn_sunist_datastructure_library::LinearSet<ElemType>::operator & (LinearSet <ElemType> set) {
    cn_sunist_datastructure_library::LinearSet<ElemType> *temp = new cn_sunist_datastructure_library::LinearSet<ElemType> (DefaultSize);
    temp->Set(list);
    return set - *temp;
}

// <!--LinkedStack--!> //
template<typename ElemType> cn_sunist_datastructure_library::LinkedStack<ElemType>::LinkedStack () {
    data = *(new cn_sunist_datastructure_library::LinkedList<ElemType>);
    length = 0;
}

template<typename ElemType> int cn_sunist_datastructure_library::LinkedStack<ElemType>::Length() {
    return length;
}

template<typename ElemType> bool cn_sunist_datastructure_library::LinkedStack<ElemType>::Empty() {
    return length == 0;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedStack<ElemType>::Push(ElemType data) {
    this->data.Push_Back(data);
    length += 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedStack<ElemType>::Pop() {
    this->data.Pop_Back();
    length -= 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedStack<ElemType>::Clear() {
    while (!data.Empty()) {
        Pop();
    }
    return success;
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::LinkedStack<ElemType>::Top() {
    return data[length-1];
}

// <!--ArrayStack--!> //
template<typename ElemType> cn_sunist_datastructure_library::ArrayStack<ElemType>::ArrayStack() {
    data = *(new cn_sunist_datastructure_library::ArrayList<ElemType>());
    length = 0;
}

template<typename ElemType> int cn_sunist_datastructure_library::ArrayStack<ElemType>::Length() {
    return length;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayStack<ElemType>::Empty() {
    return length == 0;
}

template<typename ElemType> Status cn_sunist_datastructure_library::ArrayStack<ElemType>::Push(ElemType data) {
    this->data.Push_Back(data);
    length += 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::ArrayStack<ElemType>::Pop() {
    this->data.Pop_Back();
    length -= 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::ArrayStack<ElemType>::Clear() {
    while (!data.Empty()) {
        Pop();
    }
    return success;
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::ArrayStack<ElemType>::Top() {
    return data[length-1];
}

// <!--LinkedQueue--!> //
template<typename ElemType> cn_sunist_datastructure_library::LinkedQueue<ElemType>::LinkedQueue () {
    data = *(new cn_sunist_datastructure_library::LinkedList<ElemType>());
    length = 0;
}

template<typename ElemType> int cn_sunist_datastructure_library::LinkedQueue<ElemType>::Length() {
    return length;
}

template<typename ElemType> bool cn_sunist_datastructure_library::LinkedQueue<ElemType>::Empty() {
    return length == 0;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedQueue<ElemType>::Push(ElemType data) {
    this->data.Push_Back(data);
    length += 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedQueue<ElemType>::Pop() {
    this->data.Pop_Front();
    length -= 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::LinkedQueue<ElemType>::Clear() {
    while (!data.Empty()) {
        Pop();
    }
    return success;
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::LinkedQueue<ElemType>::Front() {
    return data[0];
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::LinkedQueue<ElemType>::Back() {
    return data[length-1];
}

// <!--ArrayQueue--!> //
template<typename ElemType> cn_sunist_datastructure_library::ArrayQueue<ElemType>::ArrayQueue () {
    data = *(new cn_sunist_datastructure_library::ArrayList<ElemType>());
    length = 0;
}

template<typename ElemType> int cn_sunist_datastructure_library::ArrayQueue<ElemType>::Length() {
    return length;
}

template<typename ElemType> bool cn_sunist_datastructure_library::ArrayQueue<ElemType>::Empty() {
    return length == 0;
}

template<typename ElemType> Status cn_sunist_datastructure_library::ArrayQueue<ElemType>::Push(ElemType data) {
    this->data.Push_Back(data);
    length += 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::ArrayQueue<ElemType>::Pop() {
    this->data.Pop_Front();
    length -= 1;
    return success;
}

template<typename ElemType> Status cn_sunist_datastructure_library::ArrayQueue<ElemType>::Clear() {
    while (!data.Empty()) {
        Pop();
    }
    return success;
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::ArrayQueue<ElemType>::Front() {
    return data[0];
}

template<typename ElemType> ElemType cn_sunist_datastructure_library::ArrayQueue<ElemType>::Back() {
    return data[length-1];
}
// ================== CN_SUNIST_DATASTRUCTURE_LIBRARY_END ================= //